package com.sprouting.personal.controller;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sprouting.personal.annotations.ApiIdempotent;
import com.sprouting.personal.interfaces.common.Constant;
import com.sprouting.personal.model.common.ResultJson;
import com.sprouting.personal.model.common.jsr.AddGroup;
import com.sprouting.personal.model.common.jsr.UpdGroup;
import com.sprouting.personal.model.entity.Word;
import com.sprouting.personal.model.entity.WordGroup;
import com.sprouting.personal.service.WordGroupService;
import com.sprouting.personal.service.WordService;
import com.sprouting.personal.utils.CheckTool;
import com.sprouting.personal.utils.EntityTool;
import com.sprouting.personal.utils.IdTool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

/**
 * 单词
 *
 * @author ：LX（长沙麓谷）
 * @date 创建时间： 2023/1/3 11:30
 */
@RequestMapping("/word")
@RestController
@Slf4j
public class WordController {

    @Autowired
    private WordGroupService wordGroupService;
    @Autowired
    private WordService wordService;

    /**
     * 彩云小译的API地址
     */
    @Value("${caiyun.translate.url}")
    private String translateUrl;
    @Value("${caiyun.translate.token}")
    private String caiYunToken;

    @Value("${baiDu.translate.url}")
    private String baiDuTranslateUrl;
    @Value("${baiDu.translate.appid}")
    private String baiDuTranslateAppid;
    @Value("${baiDu.translate.securityKey}")
    private String baiDuTranslateSecurityKey;


    /**
     * 根据单词组ID查询单词
     * @param wordGroupId 单词组ID
     * @return
     */
    @PostMapping("/getWordByWordGroupId")
    public ResultJson getWordByWordGroupId(String wordGroupId){
        if (CheckTool.checkNull(wordGroupId)){
            return ResultJson.errorIllegal();
        }
        return ResultJson.success(wordService.getWordByWordGroupId(wordGroupId));
    }

    /**
     * 删除单词
     * @param id 单词ID
     * @return
     */
    @PostMapping("/delWord")
    @ApiIdempotent
    public ResultJson delWord(String id){
        if (CheckTool.checkNull(id)){
            return ResultJson.errorIllegal();
        }
        wordService.removeById(id);
        return ResultJson.success();
    }

    /**
     * 更新单词
     * @param word 单词
     * @return
     */
    @PostMapping("/updWord")
    @ApiIdempotent
    public ResultJson updWord(@Validated(UpdGroup.class) Word word){
        String msg = checkWord(word);
        if (msg != null){
            return ResultJson.error(msg);
        }

        EntityTool.buildUpdBase(word, StpUtil.getLoginIdAsString());
        wordService.updateById(word);
        return ResultJson.success();
    }

    /**
     * 保存单词
     * @param word 单词信息
     * @return
     */
    @PostMapping("/saveWord")
    @ApiIdempotent
    public ResultJson saveWord(@Validated(AddGroup.class) Word word){
        String msg = checkWord(word);
        if (msg != null){
            return ResultJson.error(msg);
        }
        if (word.getStatus() == null){
            word.setStatus(Constant.YesOrNo.YES);
        }

        word.setId(IdTool.getId());
        word.setUserId(StpUtil.getLoginIdAsString());
        EntityTool.buildSaveBase(word, StpUtil.getLoginIdAsString());
        wordService.save(word);
        return ResultJson.success();
    }


    /**
     * 分页查询单词组
     * @param page 分页条件
     * @param wordGroup 查询条件
     * @return
     */
    @PostMapping("/getWordGroupListPage")
    public ResultJson getWordGroupListPage(Page page, WordGroup wordGroup){
        if (wordGroup == null){
            wordGroup = new WordGroup();
        }
        wordGroup.setUserId(StpUtil.getLoginIdAsString());
        return ResultJson.success(wordGroupService.getWordGroupListPage(page, wordGroup));
    }

    /**
     * 物理删除单词组
     * @param id 单词组ID
     * @return
     */
    @PostMapping("/delWordGroup")
    @ApiIdempotent
    public ResultJson delWordGroup(String id){
        if (CheckTool.checkNull(id)){
            return ResultJson.errorIllegal();
        }
        Word word = wordService.getWordByWordGroupIdTop1(id);
        if (word != null){
            return ResultJson.error("当前单词组下绑定了单词，不允许删除");
        }

        wordGroupService.removeById(id);
        return ResultJson.success();
    }

    /**
     * 更新单词组
     * @param wordGroup 单词组数据
     * @return
     */
    @PostMapping("/updWordGroup")
    @ApiIdempotent
    public ResultJson updWordGroup(@Validated(UpdGroup.class) WordGroup wordGroup){
        String msg = checkWordGroup(wordGroup);
        if (msg != null){
            return ResultJson.error(msg);
        }

        EntityTool.buildUpdBase(wordGroup, StpUtil.getLoginIdAsString());
        wordGroupService.updateById(wordGroup);
        return ResultJson.success();
    }

    /**
     * 保存单词组
     * @param wordGroup 单词组数据
     * @return
     */
    @PostMapping("/saveWordGroup")
    @ApiIdempotent
    public ResultJson saveWordGroup(@Validated(AddGroup.class) WordGroup wordGroup){
        String msg = checkWordGroup(wordGroup);
        if (msg != null){
            return ResultJson.error(msg);
        }

        wordGroup.setId(IdTool.getId());
        wordGroup.setUserId(StpUtil.getLoginIdAsString());
        EntityTool.buildSaveBase(wordGroup, StpUtil.getLoginIdAsString());
        wordGroupService.save(wordGroup);
        return ResultJson.success();
    }

    /**
     * 校验单词组
     * @param wordGroup 单词组数据
     * @return
     */
    private String checkWordGroup(WordGroup wordGroup){
        WordGroup wordGroupDb = wordGroupService.getWordGroupById(wordGroup.getId(), StpUtil.getLoginIdAsString(), wordGroup.getName());
        if (wordGroupDb != null){
            return "单词组名称已使用";
        }

        return null;
    }

    /**
     * 校验单词
     * @param word 单词
     * @return
     */
    private String checkWord(Word word){
        Word wordDb = wordService.getWordByWord(word.getId(), word.getWordGroupId(), StpUtil.getLoginIdAsString(), word.getWord());
        if (wordDb != null){
            return "当前单词已添加，不需要重复添加";
        }

        // 补充数据， 2023年1月4日13:32:32 彩云的翻译结果有点一言难尽，又再次改回使用百度的翻译
        // String result = caiYunTranslate(word.getWord());
        String result = baiDuTranslate(word.getWord());
        if (CheckTool.checkNull(result)){
            return "单词解析异常，无效单词";
        }
        word.setChineseMeaning(result);
        // 读音使用有道词典的在线发音库，在audio=后面加上单词就ok了，type=0为美国发音，type=1为英国发音
        String pronunciation = String.format("http://dict.youdao.com/dictvoice?type=0&audio=%s", word.getWord());
        word.setPronunciation(pronunciation);
        return null;
    }

    /**
     * 彩云小译 的API单词调用,默认单词转中文
     * @param englishWord 要翻译的单词
     * @return 翻译结果
     */
    private String caiYunTranslate(String englishWord){
        if (CheckTool.checkNull(translateUrl, caiYunToken)){
            log.error("警告，翻译无法初始化，请检查彩云小译翻译参数配置");
            return null;
        }

        Map<String, Object> param = new HashMap<>(4);
        // 要翻译的单词
        param.put("source", englishWord);
        // 英译中（en2zh），中译英（zh2en）
        param.put("trans_type", "auto2zh");
        param.put("request_id", "web_fanyi");
        param.put("detect", true);

        String jsonStr = JSONUtil.toJsonStr(param);

        String body = HttpRequest.post(translateUrl)
                .header("content-type", "application/json")
//                .header("x-authorization", token:qgemv4jr1y38jyq6vhvi)
                .header("X-Authorization", "token:" + caiYunToken)
                .body(jsonStr).timeout(10000).execute().body();
        JSONObject jsonObject = JSONUtil.parseObj(body);
        return jsonObject.getStr("target");
    }

    /**
     * 百度翻译
     * @param englishWord 要翻译的单词
     * @return 翻译结果
     */
    private String baiDuTranslate(String englishWord){
        if (CheckTool.checkNull(baiDuTranslateAppid, baiDuTranslateSecurityKey, baiDuTranslateUrl)){
            log.error("警告，翻译无法初始化，请检查百度翻译参数配置");
            return null;
        }
        Map<String, Object> param = new HashMap<>();
        param.put("q", englishWord);
        param.put("from", "en");
        param.put("to", "zh");
        param.put("appid", baiDuTranslateAppid);
        // 随机数
        String salt = String.valueOf(System.currentTimeMillis());
        param.put("salt", salt);
        // 签名
        String sign = baiDuTranslateAppid + englishWord + salt + baiDuTranslateSecurityKey;
        String md5Hex1 = DigestUtil.md5Hex(sign);
        param.put("sign", md5Hex1);

        String html = HttpUtil.post(baiDuTranslateUrl, param);
        JSONObject jsonObject = JSONUtil.parseObj(html);
        JSONArray transResult = jsonObject.getJSONArray("trans_result");
        if (transResult != null){
            JSONObject object = transResult.getJSONObject(0);
            return object.getStr("dst");
        }
        return null;
    }
}
